<!--
 * @Author: lihaogn
 * @Date: 2022-01-19 17:47:52
 * @LastEditTime: 2022-03-11 10:50:59
 * @LastEditor: lihaogn
 * @Description: 文件的上传与下载 demo
 * @FilePath: \lix-admin-vue2\src\views\develop\demo\UploadDemo.vue
-->
<template>
  <div>
    <el-alert
      style="margin-top:10px;"
      title="文件的上传与下载"
      type="info"
      center
      :closable="false"
      effect="dark"
    >
    </el-alert>
    <div style="display:flex;margin-top:10px;">
      <div style="width:50%;border:1px dashed;padding:8px;">
        <UploadComponentDemo @fileClick="handleFileClick" />
      </div>
      <div style="display:flex;flex-direction:column;width:50%;padding:0 8px;">
        <div style="display:flex">
          <span>文件：</span>
          <el-link type="primary" :href="fileURL" download="logo.png">
            {{ fileName }}
          </el-link>
        </div>
        <span style="margin-top:8px;">下载方式：</span>

        <el-radio-group v-model="radio">
          <el-radio :label="0">a 标签</el-radio>
          <el-radio :label="1">location.href</el-radio>
          <el-radio :label="2">form 表单</el-radio>
          <el-radio :label="3">Blob</el-radio>
          <el-radio :label="4">DataURL</el-radio>
        </el-radio-group>
        <el-button type="primary" size="small" @click="handleDownload(radio)"
          >下 载</el-button
        >
      </div>
    </div>
  </div>
</template>

<script>
import { downloadRequest } from '../../../utils/request'
import UploadComponentDemo from './modules/UploadComponentDemo.vue'
export default {
  components: { UploadComponentDemo },
  data() {
    return {
      radio: 0,
      fileName: '',
      fileURL: '',
      downloadFileId: ''
    }
  },
  methods: {
    /**
     * @author: lihaogn
     * @Date: 2022-01-20 00:23:14
     * @description: 点击上传列表中文件的事件
     * @param {*} file - 被点击的文件信息
     * @return {*}
     */
    handleFileClick(file) {
      this.fileName = file.name
      if (file.id) {
        this.fileURL = file.url || ''
        this.downloadFileId = file.id
      } else {
        let response = file.response
        let url = file.url
        if (response) {
          let result = response.result
          if (result) {
            let id = result.id
            if (id) {
              this.downloadFileId = id
              this.fileURL = result.url
              return
            }
          }
        } else if (url) {
          this.fileURL = url
        } else {
          this.$message.error('数据有误，无法下载！')
        }
      }
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-26 14:17:07
     * @description: 通过 a 标签下载
     * @param {*}
     * @return {*}
     */
    downloadByAlink() {
      const a = document.createElement('a')
      a.style.display = 'none'
      a.target = '_blank'
      a.href = this.fileURL
      a.download = this.fileName
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-26 14:17:21
     * @description: 通过 js 路径方法下载
     * @param {*}
     * @return {*}
     */
    downloadByLocation() {
      // *** 浏览器可直接预览的文件下载不了，而是直接预览
      // location.href = this.fileURL
      window.open(this.fileURL)
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-26 14:17:41
     * @description: 通过表单的方式下载
     * @param {*}
     * @return {*}
     */
    downloadByForm() {
      // *** 也不能下载浏览器可直接预览的文件
      // 创建表单
      const formEle = document.createElement('form')
      formEle.action = this.fileURL
      formEle.method = 'get'
      formEle.style.display = 'none'
      // 创建 input，用于传参
      const formItem = document.createElement('input')
      formItem.value = this.fileName
      formItem.name = 'fileName'
      // 插入到页面中
      formEle.appendChild(formItem)
      document.body.appendChild(formEle)
      formEle.submit()
      document.body.removeChild(formEle)
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-26 15:57:11
     * @description: 下载文件方法
     * @param {*}
     * @return {*}
     */
    async downloadFile() {
      return await downloadRequest('/api/download', { id: this.downloadFileId })
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-26 14:17:57
     * @description: 通过 Blob 的方式下载
     * @param {*}
     * @return {*}
     */
    async downloadByBlob() {
      const res = await this.downloadFile()
      if (res.status === 200) {
        const url = URL.createObjectURL(res.data)
        const a = document.createElement('a')
        a.style.display = 'none'
        a.href = url
        a.download = this.fileName
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        URL.revokeObjectURL(url)
      }
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-26 14:18:10
     * @description: 通过 DataURL 的方式下载
     * @param {*}
     * @return {*}
     */
    async downloadByDataURL() {
      let that = this
      const res = await this.downloadFile()
      if (res.status === 200) {
        const fileReader = new FileReader()
        fileReader.readAsDataURL(res.data)
        fileReader.onload = function() {
          const a = document.createElement('a')
          a.style.display = 'none'
          a.href = this.result
          a.download = that.fileName
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
        }
      }
    },
    /**
     * @author: lihaogn
     * @Date: 2022-01-19 16:42:00
     * @description: 下载事件
     * @param {*} radioValue
     * @return {*}
     */
    handleDownload(radioValue) {
      if (this.fileName === '') {
        this.$message.warning('未选择下载文件')
        return
      }
      switch (radioValue) {
        case 0:
          // 通过 a 标签下载
          this.downloadByAlink()
          break
        case 1:
          // 通过 location 或 window.open 下载
          this.downloadByLocation()
          break
        case 2:
          // 通过表单来下载
          this.downloadByForm()
          break
        case 3:
          // 通过 Blob 来下载
          this.downloadByBlob()
          break
        case 4:
          // 通过 DataURL 来下载
          this.downloadByDataURL()
          break
        default:
          break
      }
    }
  }
}
</script>

<style lang="less" scoped>
.el-radio {
  margin: 8px;
}

/deep/.el-alert__title {
  font-size: 16px;
}
</style>
